package values.inventory
{
import core.Configuration;
import core.Language;

import flash.errors.IllegalOperationError;
import flash.events.EventDispatcher;

import values.events.InventoryValueEvent;
import values.item.IItemValue;
import values.item.ItemValue;

[Event(name="spaceExtended", type="values.events.InventoryValueEvent")]
[Event(name="spaceFull", type="values.events.InventoryValueEvent")]
[Event(name="addItemFail", type="values.events.InventoryValueEvent")]

public class InventoryValue extends EventDispatcher
{	
	[Data(type="field", mapping="@type")]
	public var key:String;
	
	[Data(type="field", mapping="@index")]
	public var index:int;
	
	[Data(type="field", mapping="@name")]
	public var baseNameKey:String;

	public function get name():String
	{
		return Language.getText(baseNameKey);
	}
	
	[Data(type="field", mapping="@desc")]
	public var baseDescKey:String;
	
	public function get desc():String
	{
		return Language.getText(baseDescKey);
	}
	
	[Data(type="field", mapping="@icon_url")]
	public var baseIconUrl:String;
	
	public function get iconUrl():String
	{
		return Configuration.assetsPath + baseIconUrl;
	}

	public function get mappingType():String
	{
		return key;
	}
    
    [Data(type="field", mapping="@is_show")]
    public var isShow:Boolean = true;
	
	private var _maxSpace:int;

    public function get maxSpace():int
    {
        return _maxSpace;
    }
    
    [Data(type="field", mapping="@max_space")]
    public function set maxSpace(value:int):void
    {
        _maxSpace = (value == -1 ? int.MAX_VALUE : value);
    }
	
	protected var _currentSpace:int;

	public function get currentSpace():int
	{
		return _currentSpace;
	}
	
	[Data(type="field", mapping="@default_space")]
	public function set currentSpace(value:int):void
	{
        if (value == -1) value = int.MAX_VALUE;
        
		var oldSpace:int = currentSpace;
		_currentSpace = value;
		
		var evt:InventoryValueEvent = new InventoryValueEvent(InventoryValueEvent.SPACE_EXTENDED);
		evt.params = { currentSpace:currentSpace, maxSpace:maxSpace, inventory:this };
		this.dispatchEvent(evt);
	}
	
	protected var _items:Vector.<IItemValue> = new Vector.<IItemValue>();
	
	public function get items():Vector.<IItemValue>
	{
		return _items;
	}
	
	public function get isFull():Boolean
	{
		if (maxSpace <= 0 || maxSpace == Number.MAX_VALUE) return false;
		return items.length >= currentSpace;
	}
    
    public function getItemByUID(uid:String):IItemValue
    {
        for each (var vo:IItemValue in items)
        {
            if (vo.uid == uid) return vo;
        }
        return null;
    }
    
    public function getItemByData(key:String, params:Object):IItemValue
    {
        throw new IllegalOperationError("<getItemByData> method should be overrided.");
    }
	
	public function addItem(value:IItemValue):*
	{
		throw new IllegalOperationError("<addItem> method should be overrided.");
	}
	
	public function removeItem(value:IItemValue):*
	{
		throw new IllegalOperationError("<removeItem> method should be overrided.");
	}
	
	public function hasEnoughSpace(value:IItemValue):Boolean
	{
		throw new IllegalOperationError("<hasEnoughSpace> method should be overrided.");
	}
	
	public function getItemNum(itemKey:String, ...args):Number
	{
		throw new IllegalOperationError("<hasEnoughSpace> method should be overrided.");
	}
    
    public function getItemNumByKey(itemKey:String):Number
    {
        throw new IllegalOperationError("<getItemNumByKey> method should be overrided.");
    }
	
	protected function findItem(itemKey:String):*
	{
		var temp:Vector.<IItemValue> = new Vector.<IItemValue>();
		for each (var vo:IItemValue in items)
		{
			if (vo.key == itemKey) temp.push(vo);
		}
		return temp;
	}
	
	protected function dispatchFullEvent():void
	{
		var evt:InventoryValueEvent = new InventoryValueEvent(InventoryValueEvent.SPACE_FULL);
		evt.params = { currentSpace:currentSpace, maxSpace:maxSpace, inventory:this };
		this.dispatchEvent(evt);
	}
	
	protected function dispatchAddItemFailEvent(target:IItemValue, flag:String = "full"):void
	{
		var evt:InventoryValueEvent = new InventoryValueEvent(InventoryValueEvent.ADD_ITEM_FAIL);
		evt.params = { flag:flag, item:target, inventory:this };
		this.dispatchEvent(evt);
	}
	
}
}



